package service

import (
	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
	"net/http"
	"smart-sensor-cloud/internal/api"
	"smart-sensor-cloud/internal/model"
	"smart-sensor-cloud/pkg/fsm"
	"smart-sensor-cloud/pkg/util"
	"strconv"
)

func GetDeviceTypes(ctx *gin.Context) {
	client := ctx.MustGet("api").(*api.Client)

	result, err := client.GetDeviceTypes()
	if err != nil {
		ctx.Set("error", &util.Error{
			Code:    http.StatusInternalServerError,
			Message: err.Error(),
		})
		return
	}

	util.ResponseOK(ctx, util.OKWithPayload(result.Data.Content))
}

func GetDevices(ctx *gin.Context) {
	sizeStr := ctx.DefaultQuery("size", "10")
	indexStr := ctx.DefaultQuery("page", "1")

	size, err := strconv.Atoi(sizeStr)
	if err != nil {
		ctx.Set("error", util.NewInvalidParameterError("参数转换失败"))
		return
	}
	index, err := strconv.Atoi(indexStr)
	if err != nil {
		ctx.Set("error", util.NewInvalidParameterError("参数转换失败"))
		return
	}

	if results, total, err := model.GetDevices(index, size); err != nil {
		ctx.Set("error", &util.Error{
			Code:    http.StatusInternalServerError,
			Message: "获取设备列表失败",
		})
		return
	} else {
		util.ResponseOK(ctx, util.OKWithPayload(&util.PaginationResp{
			Size:  size,
			Index: index,
			Data:  results,
			Total: total,
		}))
	}
}

func AddDevice(ctx *gin.Context) {
	device := new(model.Device)

	if err := ctx.MustBindWith(device, binding.JSON); err != nil {
		ctx.Set("error", util.NewInvalidParameterError(err.Error()))
		return
	}

	if err := model.AddDevice(device); err != nil {
		ctx.Set("error", &util.Error{
			Code:    http.StatusInternalServerError,
			Message: err.Error(),
		})
		return
	}

	util.ResponseOK(ctx, util.OK())
}

func UpdateDevice(ctx *gin.Context) {
	updates := new(model.Device)

	if err := ctx.MustBindWith(updates, binding.JSON); err != nil {
		ctx.Set("error", util.NewInvalidParameterError(err.Error()))
		return
	}

	deviceIDStr := ctx.Param("id")
	if deviceIDStr == "" {
		ctx.Set("error", util.NewInvalidParameterError("设备ID不可以为空"))
		return
	}

	deviceID, err := strconv.Atoi(deviceIDStr)
	if err != nil {
		ctx.Set("error", util.NewInvalidParameterError("非法的参数"))
		return
	}

	if err := model.UpdateDevice(deviceID, updates); err != nil {
		ctx.Set("error", &util.Error{
			Code:    http.StatusInternalServerError,
			Message: err.Error(),
		})
		return
	}

	util.ResponseOK(ctx, util.OK())
}

func GetDeviceWithID(ctx *gin.Context) {
	deviceIDStr := ctx.Param("id")
	if deviceIDStr == "" {
		ctx.Set("error", util.NewInvalidParameterError("设备ID不可以为空"))
		return
	}

	deviceID, err := strconv.Atoi(deviceIDStr)
	if err != nil {
		ctx.Set("error", util.NewInvalidParameterError("非法的参数"))
		return
	}

	device, err := model.GetDevice(deviceID)
	if err != nil {
		ctx.Set("error", &util.Error{
			Code:    http.StatusNotFound,
			Message: err.Error(),
		})
		return
	}

	util.ResponseOK(ctx, util.OKWithPayload(device))
}

func DeleteDevice(ctx *gin.Context) {
	deviceIDStr := ctx.Param("id")
	if deviceIDStr == "" {
		ctx.Set("error", util.NewInvalidParameterError("设备ID不可以为空"))
		return
	}

	deviceID, err := strconv.Atoi(deviceIDStr)
	if err != nil {
		ctx.Set("error", util.NewInvalidParameterError("非法的参数"))
		return
	}

	//device, err := model.GetDevice(deviceID)
	//if err != nil {
	//	ctx.Set("error", &util.Error{
	//		Code:    http.StatusNotFound,
	//		Message: err.Error(),
	//	})
	//	return
	//}
	//
	//if err := device.Delete(); err != nil {
	//	ctx.Set("error", &util.Error{
	//		Code:    http.StatusInternalServerError,
	//		Message: "删除设备失败",
	//	})
	//	return
	//}

	stateMachine := ctx.MustGet("fsm").(*fsm.StateMachine)

	if err := model.DeviceInitDelete(stateMachine, deviceID); err != nil {
		ctx.Set("error", &util.Error{
			Code:    http.StatusInternalServerError,
			Message: err.Error(),
		})
		return
	}

	util.ResponseOK(ctx, util.OK())
}

func DeviceConfirm(ctx *gin.Context) {
	deviceIDStr := ctx.Param("id")
	if deviceIDStr == "" {
		ctx.Set("error", util.NewInvalidParameterError("设备ID不可以为空"))
		return
	}

	deviceID, err := strconv.Atoi(deviceIDStr)
	if err != nil {
		ctx.Set("error", util.NewInvalidParameterError("非法的参数"))
		return
	}

	confirmType := ctx.Param("type")
	if confirmType == "" {
		ctx.Set("error", util.NewInvalidParameterError("确认类型不可为空"))
		return
	} else if confirmType != "app" && confirmType != "web" {
		ctx.Set("error", util.NewInvalidParameterError("错误的确认类型"))
		return
	}

	stateMachine := ctx.MustGet("fsm").(*fsm.StateMachine)

	if err := model.DeviceConfirm(stateMachine, deviceID, confirmType); err != nil {
		ctx.Set("error", &util.Error{
			Code:    http.StatusInternalServerError,
			Message: err.Error(),
		})
		return
	}

	util.ResponseOK(ctx, util.OK())
}
